import { getLastEvent, getLines, getSelector } from '../utils'
import tracker from '../utils/tracker'

export default function injectJsError() {
  // 普通异常
  window.addEventListener(
    'error',
    async function (e) {
      let lastEvent = await getLastEvent()

      if (e.target && (e.target.src || e.target.href)) {
        // 资源加载错误
        tracker.send({
          kind: 'stability', // 稳定性
          type: 'error', // 错误
          errorType: 'resourceError', // js错误
          message: e.message, // 错误信息
          filename: e.target.src || e.target.href, // 错误文件
          tagName: e.target.tagName, // 错误元素标
          selector: lastEvent ? getSelector(e.target) : '' // 最后一个操作的元素
        })
      } else {
        // 普通js错误
        tracker.send({
          kind: 'stability', // 稳定性
          type: 'error', // 错误
          errorType: 'jsError', // js错误
          message: e.message, // 错误信息
          filename: e.filename, // 错误文件
          position: `${e.lineno}:${e.colno}`, // 错误位置
          stack: getLines(e.error.stack), // 错误堆栈信息
          selector: lastEvent ? getSelector(lastEvent.path) : '' // 最后一个操作的元素
        })
      }
    },
    true
  )

  // Promise异常
  window.addEventListener(
    'unhandledrejection',
    async function (e) {
      let lastEvent = await getLastEvent()
      let message
      let filename
      let line = 0
      let column = 0
      let stack = ''
      let reason = e.reason

      if (typeof reason === 'string') {
        message = reason
      } else if (typeof reason === 'object') {
        message = reason.message

        if (reason.stack) {
          let matchResult = reason.stack.match(/at\s+(.+):(\d+):(\d+)/) || []
          filename = matchResult[1]
          line = matchResult[2]
          column = matchResult[3]
        }
        stack = getLines(reason.stack)
      }

      tracker.send({
        kind: 'stability', // 稳定性
        type: 'error', // 错误
        errorType: 'promiseError', // js错误
        message,
        filename,
        stack,
        position: `${line}:${column}`,
        selector: lastEvent ? getSelector(lastEvent.path) : '' // 最后一个操作的元素
      })
    },
    true
  )
}
